﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;

using Suplex.Data;

namespace sprocket
{
	public partial class MainDlg : Form
	{
		private Settings _settings = null;
		private TemplateListFile _templateListFile = new TemplateListFile();
		private DataAccessor _da = null;
		private ConnectionProperties _cp = null;
		private string _tableListSql = string.Empty;
		private string _tableInfoSql = string.Empty;
		private DataTable _tableList = null;
		private SQLCredsDlg _sqlCredsDlg = new SQLCredsDlg();
		private TableListDlg _tableListDlg = new TableListDlg();
		private bool _showEditTemplateMenuItem = true;
		private BindingNavigator _currentNavigator = null;
		private TemplateList _currentTemplateList = null;
		private string _argsLoadFile = null;


		public MainDlg(string[] args)
		{
			InitializeComponent();

			if( args.Length > 0 )
			{
				if( File.Exists( args[0] ) )
				{
					_argsLoadFile = args[0];
				}
			}
		}

		#region Startup/Shutdown
		private void MainDlg_Load(object sender, EventArgs e)
		{
			#region fix toolstrip layout
			//the stupid designer keeps rearranging the default layout for the toolbars,
			//and it's really annoying me.
			this.LoadToolStripLayout( new Point( 3, 0 ), new Point( 116, 0 ), new Point( 606, 0 ) );
			#endregion

			this.LoadSettings();

			cmbDataTemplateType.DataSource = new TemplateType[] { TemplateType.GlobalData, TemplateType.TableAwareData, TemplateType.PostProcessData };
			cmbCodeTemplateType.DataSource = new TemplateType[] { TemplateType.CSharpCode, TemplateType.TSqlCode };
			cmbOutputTemplateType.DataSource = new TemplateType[] { TemplateType.Output };
			cmbOutputTemplateType.SelectedItem = TemplateType.Output;
			cmbOutputTemplateType.Enabled = false;

			cmdTbSave.Enabled = false;

			//embedded string.IsNullOrEmpty check in LoadTemplateListFile
			this.LoadTemplateListFile( _argsLoadFile );
		}

		private void LoadSettings()
		{
			_settings = Settings.Deserialize();

			_tableListSql = Properties.Resources.tableList;
			if( !string.IsNullOrEmpty( _settings.TableListCommandOverride ) )
			{
				_tableListSql = _settings.TableListCommandOverride;
			}
			_tableListDlg.TableListCommand = _tableListSql;


			this.LoadToolStripLayout( _settings.FileToolbar, _settings.ConnectionToolbar, _settings.ExecuteToolbar );

			cmdTbAdvanced.Checked = _settings.IsAdvancedMode;
			if( !cmdTbAdvanced.Checked )
			{
				this.cmdTbAdvanced_Click( null, null );
			}

			this.LoadSettingsRecentFiles( null );
			this.LoadSettingsRecentConnections( null, null, null );
		}

		private void LoadToolStripLayout(Point tsFileLocation, Point tsConnectionLocation, Point tsExecuteLocation)
		{
			//note: for some reason, the toolstrips won't rearrange properly unless they're removed/readded to the controls collection
			if( tsFileLocation == Point.Empty ) { tsFileLocation = this.tsFile.Location; }
			if( tsConnectionLocation == Point.Empty ) { tsConnectionLocation = this.tsConnection.Location; }
			if( tsExecuteLocation == Point.Empty ) { tsExecuteLocation = this.tsExecute.Location; }

			this.tscMain.TopToolStripPanel.Controls.Remove( this.tsFile );
			this.tscMain.TopToolStripPanel.Controls.Remove( this.tsConnection );
			this.tscMain.TopToolStripPanel.Controls.Remove( this.tsExecute );

			this.tsFile.Location = tsFileLocation;
			this.tsConnection.Location = tsConnectionLocation;
			this.tsExecute.Location = tsExecuteLocation;

			this.tscMain.TopToolStripPanel.Controls.Add( this.tsFile );
			this.tscMain.TopToolStripPanel.Controls.Add( this.tsConnection );
			this.tscMain.TopToolStripPanel.Controls.Add( this.tsExecute );
		}

		private void LoadSettingsRecentFiles(string file)
		{
			if( !string.IsNullOrEmpty( file ) )
			{
				if( _settings.RecentFiles.Contains( file ) )
				{
					_settings.RecentFiles.Remove( file );
				}
				_settings.RecentFiles.Insert( 0, file );
			}

			cmdTbBrowse.DropDown.Items.Clear();
			foreach( string recentFile in _settings.RecentFiles )
			{
				cmdTbBrowse.DropDown.Items.Add( recentFile );
			}
		}

		private void LoadSettingsRecentConnections(string server, string db, string username)
		{
			if( !string.IsNullOrEmpty( server ) )
			{
				ConnectionData cd = new ConnectionData()
				{
					Server = server,
					Database = db
				};
				if( !string.IsNullOrEmpty( username ) )
				{
					cd.UserName = username;
				}

				for( int i = _settings.RecentConnections.Count - 1; i >= 0; i-- )
				{
					if( _settings.RecentConnections[i].ToString() == cd.ToString() )
					{
						_settings.RecentConnections.RemoveAt( i );
						break;
					}
				}
				_settings.RecentConnections.Insert( 0, cd );
			}

			cmdTbConnect.DropDown.Items.Clear();
			foreach( ConnectionData rcn in _settings.RecentConnections )
			{
				cmdTbConnect.DropDown.Items.Add( rcn.ToString() );
			}
		}

		private void MainDlg_FormClosing(object sender, FormClosingEventArgs e)
		{
			if( this.CheckSaveChanges() )
			{
				_settings.FileToolbar = tsFile.Location;
				_settings.ConnectionToolbar = tsConnection.Location;
				_settings.ExecuteToolbar = tsExecute.Location;
				_settings.IsAdvancedMode = cmdTbAdvanced.Checked;
				if( _tableListDlg.HaveTableListCommandOverride )
				{
					_settings.TableListCommandOverride = _tableListDlg.TableListCommand;
				}
				if( _tableListDlg.TableListCommand == Properties.Resources.tableList )
				{
					_settings.TableListCommandOverride = string.Empty;
				}
				_settings.Serialize();
			}
			else
			{
				e.Cancel = true;
			}
		}
		#endregion

		#region Database Connection
		private void cmdTbSqlCreds_Click(object sender, EventArgs e)
		{
			if( _sqlCredsDlg.ShowDialog( this ) == DialogResult.OK )
			{
				cmdTbSqlCreds.Checked = _sqlCredsDlg.WantsCredentials;
				this.cmdTbConnect_Click( null, null );
			}
		}

		private void cmdTbConnect_Click(object sender, EventArgs e)
		{
			if( cmdTbSqlCreds.Checked )
			{
				_cp = new ConnectionProperties(
					txtTbServer.Text, string.Empty, _sqlCredsDlg.UserName, _sqlCredsDlg.Password );
			}
			else
			{
				_cp = new ConnectionProperties(
					txtTbServer.Text, string.Empty );
			}
			_da = new DataAccessor( _cp.ConnectionString );

			try
			{
				DataSet ds = _da.GetDataSet( "select name from master..sysdatabases" );
				DataRow r = ds.Tables[0].NewRow();
				r["name"] = string.Empty;
				ds.Tables[0].Rows.Add( r );
				DataView v = ds.Tables[0].DefaultView;
				v.Sort = "name";
				cmbTbDatabases.ComboBox.DataSource = v;
				cmbTbDatabases.ComboBox.DisplayMember = "name";
			}
			catch( Exception ex )
			{
				cmbTbDatabases.ComboBox.DataSource = null;
				this.HandleException( "Error listing databases from sysdatabases", ex );
			}
		}

		private void cmdTbConnect_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
		{
			string[] parts = e.ClickedItem.Text.Split( '.' );
			txtTbServer.Text = parts[0];

			if( parts.Length == 3 )
			{
				_sqlCredsDlg.UseSQLServerCredentials = true;
				_sqlCredsDlg.UserName = parts[2];
				this.cmdTbSqlCreds_Click( null, null );
			}

			this.cmdTbConnect_Click( null, null );

			if( cmbTbDatabases.ComboBox.DataSource is DataView )
			{
				DataView v = (DataView)cmbTbDatabases.ComboBox.DataSource;
				foreach( DataRowView rv in v )
				{
					if( rv["name"].ToString() == parts[1] )
					{
						cmbTbDatabases.SelectedItem = rv;
						break;
					}
				}
			}
		}

		private void cmbTbDatabases_SelectedIndexChanged(object sender, EventArgs e)
		{
			if( cmbTbDatabases.SelectedItem is DataRowView )
			{
				_cp.DatabaseName = ((DataRowView)cmbTbDatabases.SelectedItem)["name"].ToString();
				if( !string.IsNullOrEmpty( _cp.DatabaseName ) )
				{
					if( _sqlCredsDlg.WantsCredentials )
					{
						_cp.BuildProprietaryString();
					}
					else
					{
						_cp.BuildIntegratedString();
					}
					_da.ConnectionString = _cp.ConnectionString;

					bool tableListOk = false;
					try
					{
						DataSet ds = _da.GetDataSet( _tableListSql );
						_tableList = ds.Tables[0];
						tableListOk = true;
					}
					catch( Exception ex )
					{
						tableListOk = false;	//just being explicit
						this.HandleException( "Error listing database tables", ex );
					}

					if( tableListOk )
					{
						lstTables.Items.Clear();
						foreach( DataRow r in _tableList.Rows )
						{
							lstTables.Items.Add( r["FULL_NAME"].ToString() );
						}

						this.LoadSettingsRecentConnections( txtTbServer.Text, _cp.DatabaseName, _cp.UserName );
					}
				}
			}
		}
		#endregion

		#region Template List functions
		private void cmdTbNew_Click(object sender, EventArgs e)
		{
			if( this.CheckSaveChanges() )
			{
				this.LoadTemplateListFile( null );
			}
		}

		private void cmdTbBrowse_Click(object sender, EventArgs e)
		{
			if( this.CheckSaveChanges() )
			{
				if( openFileDialog.ShowDialog() == DialogResult.OK )
				{
					this.LoadTemplateListFile( openFileDialog.FileName );
				}
			}
		}

		private void cmdTbBrowse_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
		{
			if( this.CheckSaveChanges() )
			{
				string file = e.ClickedItem.Text;
				if( File.Exists( file ) )
				{
					this.LoadTemplateListFile( file );
				}
				else
				{
					_settings.RecentFiles.Remove( file );
				}
			}
		}

		private void tcMain_SelectedIndexChanged(object sender, EventArgs e)
		{
			if( tcMain.SelectedTab == tpScripts )
			{
				_currentNavigator = null;
				_currentTemplateList = null;

				this.LoadTemplateNames();
			}
			else
			{
				#region select current Nav and List
				if( tcMain.SelectedTab == tpDataTemplates )
				{
					_currentNavigator = navDataTemplates;
					_currentTemplateList = _templateListFile.DataList;
				}
				else if( tcMain.SelectedTab == tpDictionaryTemplates )
				{
					_currentNavigator = navCodeTemplates;
					_currentTemplateList = _templateListFile.CodeList;
				}
				else if( tcMain.SelectedTab == tpOutputTemplates )
				{
					_currentNavigator = navOutputTemplates;
					_currentTemplateList = _templateListFile.OutputList;
				}
				#endregion

				SortedDictionary<string, Template> outputList = new SortedDictionary<string, Template>();
				foreach( Template t in _templateListFile.OutputList )
				{
					t.IsChecked = false;
					outputList[t.Name] = t;
				}

				for( int j = 0; j < lstTemplates.CheckedItems.Count; j++ )
				{
					outputList[lstTemplates.CheckedItems[j].ToString()].IsChecked = true;
				}
			}
		}

		private void LoadTemplateListFile(string file)
		{
			_templateListFile = null;

			if( !string.IsNullOrEmpty( file ) )
			{
				this.LoadSettingsRecentFiles( file );

				_templateListFile = TemplateListFile.Deserialize( file );
				this.Text = string.Format( "Mekhano SQL Sprocket: {0}", _templateListFile.FileName );
			}
			else
			{
				_templateListFile = new TemplateListFile();
				this.Text = "Mekhano SQL Sprocket";
			}

			_templateListFile.IsDirtyChanged += new EventHandler( this.TemplateListFile_IsDirtyChanged );
			this.LoadTemplateNames();

			srcDataTemplates.DataSource = _templateListFile;
			srcCodeTemplates.DataSource = _templateListFile;
			srcOutputTemplates.DataSource = _templateListFile;
		}

		void TemplateListFile_IsDirtyChanged(object sender, EventArgs e)
		{
			cmdTbSave.Enabled = _templateListFile.IsDirty;
		}

		private void LoadTemplateNames()
		{
			lstTemplates.Items.Clear();
			foreach( Template t in _templateListFile.OutputList )
			{
				if( t.TemplateType == TemplateType.Output )
				{
					lstTemplates.Items.Add( t, t.IsChecked );
				}
			}
		}

		private void cmdTbSave_Click(object sender, EventArgs e)
		{
			this.SaveFile();
		}

		private void cmdTbSaveAs_Click(object sender, EventArgs e)
		{
			this.SaveFileAs();
		}

		private bool CheckSaveChanges()
		{
			if( _templateListFile.IsDirty )
			{
				bool ok = false;

				DialogResult result = MessageBox.Show( this,
					string.Format( "Do you want to save changes to {0}?",
					string.IsNullOrEmpty( _templateListFile.FileName ) ? "your templates" : _templateListFile.FileName ),
					"Save changes?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button3 );

				switch( result )
				{
					case DialogResult.Yes:
					{
						ok = this.SaveFile();
						break;
					}
					case DialogResult.No:
					{
						ok = true;
						break;
					}
					case DialogResult.Cancel:
					{
						ok = false;
						break;
					}
				}

				return ok;
			}
			else
			{
				return true;
			}
		}

		private bool SaveFile()
		{
			bool ok = _templateListFile.FileName != null;
			if( !ok )
			{
				ok = this.SaveFileAs();
			}
			else
			{
				_templateListFile.Serialize();
				_templateListFile.IsDirty = false;
				this.Text = string.Format( "SQL Sprocket: {0}", _templateListFile.FileName );
				ok = true;
			}

			return ok;
		}

		private bool SaveFileAs()
		{
			bool ok = false;
			SaveFileDialog dlg = new SaveFileDialog();
			dlg.Filter = "SQLsprocket File|*.ssproc";
			if( dlg.ShowDialog( this ) == DialogResult.OK )
			{
				_templateListFile.FileName = dlg.FileName;

				ok = this.SaveFile();
			}

			return ok;
		}

		private void cmdTbAdvanced_Click(object sender, EventArgs e)
		{
			if( cmdTbAdvanced.Checked )
			{
				tcMain.TabPages.Insert( 1, tpDataTemplates );
				tcMain.TabPages.Insert( 2, tpDictionaryTemplates );
			}
			else
			{
				tcMain.TabPages.Remove( tpDataTemplates );
				tcMain.TabPages.Remove( tpDictionaryTemplates );
			}
		}

		private void cmdEditTableListCommand_Click(object sender, EventArgs e)
		{
			if( _tableListDlg.ShowDialog( this ) == DialogResult.OK )
			{
				_tableListSql = _tableListDlg.TableListCommand;
			}
		}
		#endregion

		#region convenience functions
		protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
		{
			if( keyData == (Keys.Control | Keys.E) )
			{
				this.cmdTbExecute_Click( null, null );
				return true;
			}
			else if( keyData == (Keys.Control | Keys.O) )
			{
				this.cmdTbBrowse_Click( null, null );
				return true;
			}
			else if( keyData == (Keys.Control | Keys.N) )
			{
				this.cmdTbNew_Click( null, null );
				return true;
			}
			else if( keyData == (Keys.Control | Keys.S) )
			{
				if( cmdTbSave.Enabled )
				{
					this.SaveFile();
				}
				return true;
			}
			else if( keyData == (Keys.Control | Keys.Shift | Keys.S) )
			{
				this.SaveFileAs();
				return true;
			}
			else if( keyData == Keys.F1 )
			{
				this.helpToolStripButton_Click( null, null );
				return true;
			}

			return base.ProcessCmdKey( ref msg, keyData );
		}

		private void lstTemplates_MouseDown(object sender, MouseEventArgs e)
		{
			if( e.Button == MouseButtons.Right )
			{
				lstTemplates.SelectedIndex = lstTemplates.IndexFromPoint( e.Location );
				_showEditTemplateMenuItem = lstTemplates.SelectedIndex > -1;
			}
		}

		private void ctxTemplates_Opening(object sender, System.ComponentModel.CancelEventArgs e)
		{
			e.Cancel = lstTemplates.Items.Count == 0;
			mnuEditTemplate.Visible =
				mnuCtxTemplateSep0.Visible = _showEditTemplateMenuItem;
			_showEditTemplateMenuItem = false;
		}

		private void lstTables_MouseDown(object sender, MouseEventArgs e)
		{
			if( e.Button == MouseButtons.Right )
			{
				lstTables.SelectedIndex = lstTables.IndexFromPoint( e.Location );
			}
		}

		private void ctxTables_Opening(object sender, System.ComponentModel.CancelEventArgs e)
		{
			e.Cancel = lstTables.Items.Count == 0;
		}

		private void mnuEditTemplate_Click(object sender, EventArgs e)
		{
			tcMain.SelectedTab = tpOutputTemplates;
			navOutputTemplates.BindingSource.Position = lstTemplates.SelectedIndex;
		}

		private void mnuCheckAllTemplates_Click(object sender, EventArgs e)
		{
			for( int i = 0; i < lstTemplates.Items.Count; i++ )
			{
				lstTemplates.SetItemChecked( i, true );
			}
		}

		private void mnuUncheckAllTemplates_Click(object sender, EventArgs e)
		{
			foreach( int i in lstTemplates.CheckedIndices )
			{
				lstTemplates.SetItemChecked( i, false );
			}
		}

		private void mnuCheckAllTables_Click(object sender, EventArgs e)
		{
			for( int i = 0; i < lstTables.Items.Count; i++ )
			{
				lstTables.SetItemChecked( i, true );
			}
		}

		private void mnuUncheckAllTables_Click(object sender, EventArgs e)
		{
			foreach( int i in lstTables.CheckedIndices )
			{
				lstTables.SetItemChecked( i, false );
			}
		}
		#endregion

		#region template reordering
		private void cmdTemplateMoveUp_Click(object sender, EventArgs e)
		{
			int i = _currentNavigator.BindingSource.Position;
			if( i > 0 )
			{
				this.MoveTemplateListItem( i, i - 1 );
			}
		}

		private void cmdTemplateMoveDown_Click(object sender, EventArgs e)
		{
			int i = _currentNavigator.BindingSource.Position;
			if( i < _currentTemplateList.Count - 1 )
			{
				this.MoveTemplateListItem( i, i + 1 );
			}
		}

		private void MoveTemplateListItem(int oldIndex, int newIndex)
		{
			Template t = _currentTemplateList[oldIndex];
			_currentNavigator.BindingSource.RemoveAt( oldIndex );
			_currentNavigator.BindingSource.Insert( newIndex, t );
			_currentNavigator.BindingSource.Position = newIndex;
		}

		private void cmdDataTemplateMoveLeft_EnabledChanged(object sender, EventArgs e)
		{
			cmdDataTemplateMoveUp.Enabled = cmdDataTemplateMoveLeft.Enabled;
		}
		private void cmdDataTemplateMoveRight_EnabledChanged(object sender, EventArgs e)
		{
			cmdDataTemplateMoveDown.Enabled = cmdDataTemplateMoveRight.Enabled;
		}

		private void cmdCodeTemplateMoveLeft_EnabledChanged(object sender, EventArgs e)
		{
			cmdCodeTemplateMoveUp.Enabled = cmdCodeTemplateMoveLeft.Enabled;
		}
		private void cmdCodeTemplateMoveRight_EnabledChanged(object sender, EventArgs e)
		{
			cmdCodeTemplateMoveDown.Enabled = cmdCodeTemplateMoveRight.Enabled;
		}

		private void cmdOutputTemplateMoveLeft_EnabledChanged(object sender, EventArgs e)
		{
			cmdOutputTemplateMoveUp.Enabled = cmdOutputTemplateMoveLeft.Enabled;
		}
		private void cmdOutputTemplateMoveRight_EnabledChanged(object sender, EventArgs e)
		{
			cmdOutputTemplateMoveDown.Enabled = cmdOutputTemplateMoveRight.Enabled;
		}
		#endregion

		#region help, about, and error handling
		private void helpToolStripButton_Click(object sender, EventArgs e)
		{
			string helpDoc = string.Format( @"{0}\SQLSprocket_UserGuide.pdf", Application.StartupPath );
			if( File.Exists( helpDoc ) )
			{
				ProcessStartInfo psi = new ProcessStartInfo( helpDoc );
				Process.Start( psi );
			}
			else
			{
				this.HandleException( "Could not find User Guide",
					new Exception( string.Format( "Could not find file: {0}", helpDoc ) ) );
			}
		}

		private void cmdAbout_Click(object sender, EventArgs e)
		{
			AboutDlg about = new AboutDlg();
			about.ShowDialog( this );
		}

		//TODO: this is just a stub, need to implement something a little more robust...
		private void HandleException(string caption, Exception ex)
		{
			MessageBox.Show( this, ex.Message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error );
		}
		#endregion


		private void cmdTbExecute_Click(object sender, EventArgs e)
		{
			ScriptEngine scripter = new ScriptEngine();
			DataSet ds = new DataSet();
			SortedDictionary<string, string> vars = new SortedDictionary<string, string>();
			string currentTable = string.Empty;
			bool compileAndExecuteOk = false;
			List<string> errorMessages = new List<string>();


			#region gather OutputList templates
			SortedDictionary<string, Template> outputList = new SortedDictionary<string, Template>();
			foreach( Template t in _templateListFile.OutputList )
			{
				outputList[t.Name] = t;
			}
			#endregion

			tcMain.SelectedTab = tpScripts;
			txtScripts.Clear();


			//populate global-scope data
			foreach( Template t in _templateListFile.GlobalDataList )
			{
				try
				{
					scripter.ExecuteSql( t, null, ref ds, _da );
				}
				catch( Exception ex )
				{
					errorMessages.Add( string.Format( "Error executing GlobalData SQL: {0}\r\n\r\n{1}", t.Name, ex ) );
				}
			}


			//loop through checked tables
			for( int i = 0; i < lstTables.CheckedItems.Count; i++ )
			{
				currentTable = string.Format( "{0}.{1}", cmbTbDatabases.Text, lstTables.CheckedItems[i].ToString() );


				//populate table-scope data
				foreach( Template t in _templateListFile.TableAwareDataList )
				{
					try
					{
						scripter.ExecuteSql( t, currentTable, ref ds, _da );
					}
					catch( Exception ex )
					{
						errorMessages.Add( string.Format( "Error executing TableAware SQL Code Error: {0}\r\n\r\n{1}", t.Name, ex ) );
					}
				}


				//build data dictionary
				compileAndExecuteOk = true;
				foreach( Template t in _templateListFile.CodeList )
				{
					switch( t.TemplateType )
					{
						case TemplateType.CSharpCode:
						{
							compileAndExecuteOk =
								scripter.ExecuteCSharpCode( t, ds, currentTable, ref vars );
							break;
						}
						case TemplateType.TSqlCode:
						{
							try
							{
								scripter.ExecuteTSqlCode( t, currentTable, ref vars, _da );
							}
							catch( Exception ex )
							{
								compileAndExecuteOk = false;
								errorMessages.Add( string.Format( "TSQL Code Error: {0}\r\n\r\n{1}", t.Name, ex ) );
							}
							break;
						}
					}

					if( !compileAndExecuteOk )
					{
						break;
					}
				}


				//create output templates
				if( compileAndExecuteOk )
				{
					string buf = string.Empty;
					for( int j = 0; j < lstTemplates.CheckedItems.Count; j++ )
					{
						buf = outputList[lstTemplates.CheckedItems[j].ToString()].ScriptTemplate;
						if( buf.StartsWith( "<DumpDictionary>" ) )
						{
							buf = string.Empty;
							foreach( KeyValuePair<string, string> kvp in vars )
							{
								txtScripts.AppendText(
									string.Format( "********************* {0} *********************\r\n{1}\r\n\r\n",
									kvp.Key, kvp.Value ) );
							}
						}
						else
						{
							foreach( KeyValuePair<string, string> kvp in vars )
							{
								buf = Regex.Replace( buf, kvp.Key, kvp.Value );
							}
						}

						txtScripts.AppendText( buf );
						buf = string.Empty;
					}
				}
				else
				{
					foreach( string err in vars.Values )
					{
						errorMessages.Add( err );
					}
				}
			}


			//execute cleanup data templates
			foreach( Template t in _templateListFile.PostProcessDataList )
			{
				try
				{
					scripter.ExecuteSql( t, null, ref ds, _da );
				}
				catch( Exception ex )
				{
					errorMessages.Add( string.Format( "Error executing PostProcessData: {0}\r\n\r\n{1}", t.Name, ex ) );
				}
			}


			if( errorMessages.Count > 0 )
			{
				txtScripts.AppendText( string.Format( "\r\n\r\n*************** {0} Error{1}! ***************",
					errorMessages.Count, errorMessages.Count > 1 ? "s" : string.Empty ) );
				foreach( string err in errorMessages )
				{
					txtScripts.AppendText( string.Format( "\r\n\r\n{0}\r\n\r\n", err ) );
				}
			}


			scripter = null;
		}
	}
}